package com.linsen.core.common.util;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Date;

/**
 * LocalDateTime工具类
 *
 * @author zhaoyong
 * @date 2023/4/3
 */
public final class LocalDateTimeUtil {
    public static final ZoneOffset DEFAULT_ZONE_OFFSET = ZoneOffset.ofHours(8);

    public static final DateTimeFormatter DEFAULT_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
    public static final DateTimeFormatter YYYYMMDDHHMMSS = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
    public static final DateTimeFormatter DEFAULT_DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    public static final DateTimeFormatter YYYYMMDD = DateTimeFormatter.ofPattern("yyyyMMdd");
    public static final DateTimeFormatter DEFAULT_MONTH_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM");
    public static final DateTimeFormatter YYYYMM = DateTimeFormatter.ofPattern("yyyyMM");
    public static final DateTimeFormatter DEFAULT_YEAR_FORMATTER = DateTimeFormatter.ofPattern("yyyy");
    public static final DateTimeFormatter YYYY = DateTimeFormatter.ofPattern("yyyy");

    /**
     * 当前时间
     *
     * @return
     */
    public static LocalDateTime now() {
        return LocalDateTime.now(DEFAULT_ZONE_OFFSET);
    }

    /**
     * LocalDate转Date
     *
     * @param localDate
     * @return
     */
    public static Date toDate(LocalDate localDate) {
        return Date.from(localDate.atStartOfDay(DEFAULT_ZONE_OFFSET).toInstant());
    }

    /**
     * LocalDateTime转Date
     *
     * @param localDateTime
     * @return
     */
    public static Date toDate(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(DEFAULT_ZONE_OFFSET).toInstant());
    }

    /**
     * Date转LocalDate
     *
     * @param date
     * @return
     */
    public static LocalDate toLocalDate(Date date) {
        return date.toInstant().atZone(DEFAULT_ZONE_OFFSET).toLocalDate();
    }

    /**
     * Date转LocalDateTime
     *
     * @param date
     * @return
     */
    public static LocalDateTime toLocalDateTime(Date date) {
        return date.toInstant().atZone(DEFAULT_ZONE_OFFSET).toLocalDateTime();
    }

    /**
     * LocalDate转时间戳
     *
     * @param localDate
     * @return
     */
    public static long toTimestamp(LocalDate localDate) {
        return localDate.atStartOfDay(DEFAULT_ZONE_OFFSET).toInstant().toEpochMilli();
    }

    /**
     * LocalDateTime转时间戳
     *
     * @param localDateTime
     * @return
     */
    public static long toTimestamp(LocalDateTime localDateTime) {
        return localDateTime.toInstant(DEFAULT_ZONE_OFFSET).toEpochMilli();
    }

    /**
     * Duration转时间戳
     *
     * @param duration
     * @return
     */
    public static long toPlusTimestamp(Duration duration) {
        LocalDateTime localDateTime = now().plusNanos(duration.toNanos());
        return toTimestamp(localDateTime);
    }

    /**
     * Duration转时间戳
     *
     * @param duration
     * @return
     */
    public static long toMinusTimestamp(Duration duration) {
        LocalDateTime localDateTime = now().minusNanos(duration.toNanos());
        return toTimestamp(localDateTime);
    }

    /**
     * 时间戳转LocalDate
     *
     * @param timestamp
     * @return
     */
    public static LocalDate toLocalDate(long timestamp) {
        return Instant.ofEpochMilli(timestamp).atZone(DEFAULT_ZONE_OFFSET).toLocalDate();
    }

    /**
     * 时间戳转LocalDateTime
     *
     * @param timestamp
     * @return
     */
    public static LocalDateTime toLocalDateTime(long timestamp) {
        return Instant.ofEpochMilli(timestamp).atZone(DEFAULT_ZONE_OFFSET).toLocalDateTime();
    }

    /**
     * LocalDateTime格式化
     *
     * @param localDateTime
     * @return
     */
    public static String format(LocalDateTime localDateTime) {
        return localDateTime.format(DEFAULT_DATE_TIME_FORMATTER);
    }

    /**
     * LocalDateTime格式化
     *
     * @param localDateTime
     * @param pattern
     * @return
     */
    public static String format(LocalDateTime localDateTime, String pattern) {
        return localDateTime.format(DateTimeFormatter.ofPattern(pattern));
    }
}
